package ace.cmp.sharding.dynamic.datasource.autoconfig;

import ace.cmp.sharding.dynamic.datasource.core.constant.ShardingDynamicDataSourceConstants;
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAssistConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import java.util.Map;
import javax.sql.DataSource;
import lombok.AllArgsConstructor;
import org.apache.shardingsphere.spring.boot.ShardingSphereAutoConfiguration;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author caspar
 * @date 2023/3/9 15:58
 */
@AllArgsConstructor
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class})
@AutoConfigureAfter({
  ShardingSphereAutoConfiguration.class,
  DynamicDataSourceAssistConfiguration.class
})
@Configuration
public class ShardingDynamicDataSourceAutoConfig {

  /**
   * 动态数据源集成sharding-jdbc 数据源
   *
   * @return
   */
  @Bean
  public DynamicDataSourceProvider dynamicDataSourceProvider(
      DefaultDataSourceCreator dataSourceCreator,
      DynamicDataSourceProperties properties,
      ObjectProvider<DataSource> shardingDataSourceObjectProvider) {
    Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
    return new AbstractDataSourceProvider(dataSourceCreator) {
      @Override
      public Map<String, DataSource> loadDataSources() {
        Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
        // 将 shardingjdbc 管理的数据源也交给动态数据源管理
        if (shardingDataSourceObjectProvider.getIfAvailable() != null) {
          dataSourceMap.put(
              ShardingDynamicDataSourceConstants.DEFAULT_SHARDING_DATA_SOURCE_NAME,
              shardingDataSourceObjectProvider.getIfAvailable());
        }
        return dataSourceMap;
      }
    };
  }
}
